<?php

/**
 * ## TbPager class file.
 *
 * @author Christoffer Niska <ChristofferNiska@gmail.com>
 * @copyright Copyright &copy; Christoffer Niska 2011-
 * @license [New BSD License](http://www.opensource.org/licenses/bsd-license.php)
 */

/**
 * ## Bootstrap pager.
 *
 * @see <http://twitter.github.com/bootstrap/components.html#pagination>
 *
 * @package booster.widgets.supplementary
 */
class TbPager extends CLinkPager {
    // Pager alignments.

    const ALIGNMENT_CENTER = 'centered';
    const ALIGNMENT_RIGHT = 'right';

    /**
     * @var string attributes for the pager container tag.
     */
    public $containerTag = 'div';

    /**
     * @var array HTML attributes for the pager container tag.
     */
    public $containerHtmlOptions = array();

    /**
     * @var string the pager alignment.
     * Valid values are 'centered' and 'right'.
     */
    public $alignment = self::ALIGNMENT_RIGHT;

    /**
     * @var string the text shown before page buttons.
     * Defaults to an empty string, meaning that no header will be displayed.
     */
    public $header = '';

    /**
     * @var string the URL of the CSS file used by this pager.
     * Defaults to false, meaning that no CSS will be included.
     */
    public $cssFile = false;

    /**
     * @var boolean whether to display the first and last items.
     */
    public $displayFirstAndLast = false;
    
    public $loadMore = false;
    public $loadMoreButton = 'Load more...';

    /**
     * ### .init()
     *
     * Initializes the pager by setting some default property values.
     */
    public function init() {

        if ($this->nextPageLabel === null) {
            $this->nextPageLabel = '&raquo;';
        }

        if ($this->prevPageLabel === null) {
            $this->prevPageLabel = '&laquo;';
        }

        $classes = array('pagination');

        /* TODO: move these to styles files! */
        $style = '';
        $containerStyle = '';

        $validAlignments = array(self::ALIGNMENT_CENTER, self::ALIGNMENT_RIGHT);

        if (in_array($this->alignment, $validAlignments)) {
            if ($this->alignment == self::ALIGNMENT_RIGHT)
                $classes[] = 'pull-right';

            if ($this->alignment == self::ALIGNMENT_CENTER) {
                // $style = 'margin-left: auto; margin-right: auto;'; // not needed!
                $containerStyle = 'text-align: center;';
            }
        }

        if (!empty($classes)) {
            $classes = implode(' ', $classes);
            if (isset($this->htmlOptions['class'])) {
                $this->htmlOptions['class'] = ' ' . $classes;
            } else {
                $this->htmlOptions['class'] = $classes;
            }
        }

        if (!empty($style)) {
            if (isset($this->htmlOptions['style']) && !empty($this->htmlOptions['style']))
                $this->htmlOptions['style'] .= ' ' . $style;
            else
                $this->htmlOptions['style'] = $style;
        }

        if (!empty($containerStyle)) {
            if (isset($this->containerHtmlOptions['style']) && !empty($this->containerHtmlOptions['style']))
                $this->containerHtmlOptions['style'] .= ' ' . $containerStyle;
            else
                $this->containerHtmlOptions['style'] = $containerStyle;
        }

        parent::init();
    }

    /**
     * Executes the widget.
     * This overrides the parent implementation by displaying the generated page buttons.
     */
    public function run() {

        $this->registerClientScript();
        if ($this->loadMore) {
            $this->createPageMoreButtons();
        } else {
            $buttons = $this->createPageButtons();
            if (empty($buttons))
                return;
            echo CHtml::openTag($this->containerTag, $this->containerHtmlOptions);
            echo $this->header;
            echo CHtml::tag('ul', $this->htmlOptions, implode("\n", $buttons));
            echo '<div style="clear: both;"></div>';
            echo $this->footer;
            echo CHtml::closeTag($this->containerTag);
        }
    }

    protected function createPageMoreButtons() {
        if (($pageCount = $this->getPageCount()) <= 1) {
            return array();
        }
        $currentPage = $this->getCurrentPage(false);
        if (($page = $currentPage + 1) >= $pageCount) {
            $page = 0;
        }
        if ($page) { 
            echo CHtml::openTag($this->containerTag, $this->containerHtmlOptions);
            echo $this->header;
            echo CHtml::link($this->loadMoreButton, $this->createPageUrl($page), array('class'=>'btn btn-primary btn-block','data-loading-text'=>Yii::t('app', 'Memuat data berikut...')));
            echo $this->footer;
            echo CHtml::closeTag($this->containerTag);
            Yii::app()->clientScript->registerScript('loadingText', "$('.pagination a').click(function(){ $(this).button('loading'); });");
        } else {
            return;
        }
    }

    /**
     * ### .createPageButtons()
     *
     * Creates the page buttons.
     * @return array a list of page buttons (in HTML code).
     */
    protected function createPageButtons() {

        if (($pageCount = $this->getPageCount()) <= 1) {
            return array();
        }

        list ($beginPage, $endPage) = $this->getPageRange();

        $currentPage = $this->getCurrentPage(false); // currentPage is calculated in getPageRange()

        $buttons = array();

        // first page
        if ($this->displayFirstAndLast) {
            $buttons[] = $this->createPageButton($this->firstPageLabel, 0, 'first', $currentPage <= 0, false);
        }

        // prev page
        if (($page = $currentPage - 1) < 0) {
            $page = 0;
        }

        $buttons[] = $this->createPageButton($this->prevPageLabel, $page, 'previous', $currentPage <= 0, false);

        // internal pages
        for ($i = $beginPage; $i <= $endPage; ++$i) {
            $buttons[] = $this->createPageButton($i + 1, $i, '', false, $i == $currentPage);
        }

        // next page
        if (($page = $currentPage + 1) >= $pageCount - 1) {
            $page = $pageCount - 1;
        }

        $buttons[] = $this->createPageButton(
                $this->nextPageLabel, $page, 'next', $currentPage >= ($pageCount - 1), false
        );

        // last page
        if ($this->displayFirstAndLast) {
            $buttons[] = $this->createPageButton(
                    $this->lastPageLabel, $pageCount - 1, 'last', $currentPage >= ($pageCount - 1), false
            );
        }

        return $buttons;
    }

    /**
     * ### .createPageButton()
     *
     * Creates a page button.
     * You may override this method to customize the page buttons.
     *
     * @param string $label the text label for the button
     * @param integer $page the page number
     * @param string $class the CSS class for the page button. This could be 'page', 'first', 'last', 'next' or 'previous'.
     * @param boolean $hidden whether this page button is visible
     * @param boolean $selected whether this page button is selected
     *
     * @return string the generated button
     */
    protected function createPageButton($label, $page, $class, $hidden, $selected) {
        if ($hidden || $selected) {
            $class .= ' ' . ($hidden ? 'disabled' : 'active');
        }

        return CHtml::tag('li', array('class' => $class), CHtml::link($label, $this->createPageUrl($page)));
    }

}
